package com.nas.app.task;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

public class Parse {

    public Task parse(String taskString) throws ParseException {
        Task task = new Task();

        char[] taskCharArray = taskString.toCharArray();
        
        
        boolean waitBeginTask = true;
        boolean waitEndTask = false;
        boolean waitBeginNamedArgument = false;
        boolean waitEndNamedArgument = false;
        boolean waitForSeparatorOrArgument = false;
        boolean waitBeginArgumentValue = false;
        boolean waitEndArgumentValue = false;
        boolean onlyArgumentValue = false;
        StringBuffer stringBuffer = new StringBuffer();
        String argumenNameOrValue = null;  
        List<Argument> arguments = new ArrayList<Argument>();
        Argument argument = null;
        int i;
        for (i=0; i < taskCharArray.length; i++) {
            
            if (waitBeginTask) { 
                if (Character.isLetterOrDigit(taskCharArray[i])) {
                    waitEndTask = true;
                    waitBeginTask = false;
                    stringBuffer.append(Character.toUpperCase(taskCharArray[i]));
                }
                continue;
            }
            if (waitEndTask) {
                if (Character.isLetterOrDigit(taskCharArray[i])) {
                    stringBuffer.append(taskCharArray[i]);
                } else if (Character.isSpaceChar(taskCharArray[i])) {
                    waitEndTask = false;
                    waitBeginNamedArgument = true;
                    task.setTaskName(stringBuffer.toString());                    
                    stringBuffer = new StringBuffer();
                }
                continue;
            }
            if (waitBeginNamedArgument) {
                if (Character.isLetterOrDigit(taskCharArray[i])) {
                    waitEndNamedArgument = true;
                    waitBeginNamedArgument = false;
                    stringBuffer.append(taskCharArray[i]);
                }
                continue;
            }
            if (waitEndNamedArgument) {
                if (Character.isSpaceChar(taskCharArray[i])) {
                    waitForSeparatorOrArgument = true;
                    waitEndNamedArgument = false;
                    argumenNameOrValue = stringBuffer.toString();
                    stringBuffer = new StringBuffer();
                } else if (taskCharArray[i] == ':') {
                    waitBeginArgumentValue = true;
                    waitEndNamedArgument = false;
                    argumenNameOrValue = stringBuffer.toString();
                    argument = new Argument();
                    argument.setArgumentName(argumenNameOrValue);
                    stringBuffer = new StringBuffer();
                } else {
                    stringBuffer.append(taskCharArray[i]);
                }
                continue;
            }
            if (waitForSeparatorOrArgument) {
                if (taskCharArray[i] == ':') {
                    waitForSeparatorOrArgument = false;
                    waitBeginArgumentValue = true;
                    argument = new Argument();
                    argument.setArgumentName(argumenNameOrValue);
                    stringBuffer = new StringBuffer();
                    
                } else if (Character.isLetterOrDigit(taskCharArray[i])) {
                    waitForSeparatorOrArgument = false;
                    waitEndArgumentValue = true;
                    onlyArgumentValue = true;
                    argument = new Argument();
                    argument.setArgumentValue(argumenNameOrValue);
                    arguments.add(argument);
                    stringBuffer = new StringBuffer();
                    stringBuffer.append(taskCharArray[i]);
                } 
                continue;
            }
            if (waitBeginArgumentValue) {
                if (Character.isLetterOrDigit(taskCharArray[i])) {
                    stringBuffer.append(taskCharArray[i]);
                    waitBeginArgumentValue = false;
                    waitEndArgumentValue = true;
                }
                continue;
            }
            if (waitEndArgumentValue) {
                if (Character.isSpaceChar(taskCharArray[i])) {
                    waitEndArgumentValue = false;
                    if (onlyArgumentValue) {
                        waitBeginArgumentValue = true;
                        argument = new Argument();
                    } else {
                        waitBeginNamedArgument = true;
                    }
                    argument.setArgumentValue(stringBuffer.toString());
                    arguments.add(argument);
                    stringBuffer = new StringBuffer();
                } else {
                    stringBuffer.append(taskCharArray[i]);
                }
                continue;
            }              
        }
         
        if (waitEndArgumentValue) {
            if (onlyArgumentValue) {
                argument = new Argument();
            }
            argument.setArgumentValue(stringBuffer.toString());
            arguments.add(argument);
        }
        if (waitEndNamedArgument) {
            if (stringBuffer.length() == 0){
                throw new ParseException("Error al parsear columna [" +i+ "], se esperaba un argumento", i);    
            }
            argument.setArgumentName(stringBuffer.toString());
            arguments.add(argument);
        }
        
        if (waitEndTask) {
            task.setTaskName(stringBuffer.toString());
        }
        task.setArguments(arguments);
        
//        String[] taskSplit = taskString.split("[\\s]+");
//        task.setTaskName(taskSplit[0].trim());
//        String argumentString = taskString.substring(taskString.indexOf(taskSplit[0])+taskSplit[0].length());
//        argumentString = argumentString.replaceAll("[\\s]*:[\\s]*", ":");
//        
//        List<Argument> arguments = new ArrayList<Argument>();
//        String[] argumentsSplit = argumentString.split("[\\s]+");
//        String[] argumentSplit;
//        for (int i = 1; i < argumentsSplit.length; i++) {
//            Argument argument = new Argument();
//            argumentSplit = argumentsSplit[i].split("[\\s]*:[\\s]*");
//            if (argumentSplit.length > 0) {
//                if (argumentSplit.length == 2) {
//                    argument.setArgumentName(argumentSplit[0]);
//                    argument.setArgumentValue(argumentSplit[1]);
//                } else {
//                    argument.setArgumentValue(argumentSplit[0]);
//                }
//                arguments.add(argument);
//            }
//        }
//        task.setArguments(arguments);
        return task;
    }

}
